home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / mg / rib / mgribtoken.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-30  |  15.3 KB  |  657 lines

  1. /*
  2.  * NOTES:
  3.  * 1. mrti() assumes unsigned short is 2 bytes, MSB first
  4.  *    this may have to change for other architecture
  5.  * 2. will it be possible to increase the encoded float array length
  6.  *    by "adding l" to create 256 aggregates of 3 or 4 floats each, as
  7.  *    opposed to 256 straight floats? (see appendix C, pg 163 of the
  8.  *    'big' renderman manual)
  9.  * 3. the name mrti should be changed to mgri (it sounds better)
  10.  */
  11.  
  12. #include "mgribtoken.h"
  13. #include <stdio.h>
  14.  
  15. #include "mg.h"
  16. #include "mgribP.h"
  17. #include "mgrib.h"
  18.  
  19. #ifdef test
  20. #include <stdio.h>
  21. #endif
  22.  
  23. #define BUFFERSIZE 1024*128    /* 128k buffer */
  24. #define TMPSIZE 8192
  25. #define SECTIONWIDTH 70        /* width of a section header */
  26.  
  27. #define STRINGDEF    0315
  28. #define STRINGREF    0317
  29. #define LNGSTRINGENCODE    0241   /* length follows, is unsigned short */
  30. #define STRINGENCODE    0220
  31. #define RIREQDEF    0314
  32. #define RIREQREF    0246
  33. #define FLOATARRAYDEF    0310
  34. #define INTEGER        0201   /* unsigned short */
  35. #define FLOAT        0244
  36.  
  37. void binary_token(int a1, va_list *alist);
  38. void ascii_token(int a1, va_list *alist);
  39.  
  40. unsigned char *tokenbuffer=NULL;
  41. unsigned char *limit;
  42. unsigned char *ptr;
  43.  
  44. /* following is the table: see mgribtoken.h (struct) for desc of fields */
  45. static struct _table table[] = {
  46.     {"", 0, 0, 0},        /* mr_NULL */
  47.  
  48.     /* Ri Requests */
  49.     {"AttributeBegin",        14,  0, 0},
  50.     {"AttributeEnd",        12,  1, 0},
  51.     {"TransformBegin",        14,  2, 0},
  52.     {"TransformEnd",        12,  3, 0},
  53.     {"Identity",         8,  4, 0},
  54.     {"ConcatTransform",        15,  5, 0},
  55.     {"Surface",             7,  6, 0},
  56.     {"ShadingInterpolation",    20,  7, 0},
  57.     {"Color",              5,  8, 0},
  58.     {"Opacity",             7,  9, 0},
  59.     {"Polygon",             7, 10, 0},
  60.     {"PatchMesh",         9, 11, 0},
  61.     {"Format",             6, 12, 0},
  62.     {"Projection",        10, 13, 0},
  63.     {"Clipping",         8, 14, 0},
  64.     {"WorldBegin",        10, 15, 0},
  65.     {"WorldEnd",         8, 16, 0},
  66.     {"Display",             7, 17, 0},
  67.     {"ScreenWindow",        12, 19, 0},
  68.     {"LightSource",        11, 20, 0},
  69.     {"Sphere",             6, 21, 0},
  70.     {"Translate",         9, 22, 0},
  71.     {"Rotate",             6, 23, 0},
  72.     {"Cylinder",         8, 24, 0},
  73.     {"NuPatch",             7, 25, 0},
  74.     {"ShadingRate",        11, 26, 0},
  75.     {"Option",             6, 27, 0},
  76.     {"Illuminate",        10, 28, 0},
  77.     {"FrameBegin",        10, 29, 0},
  78.     {"FrameEnd",         8, 30, 0},
  79.  
  80.     /* following are reserved - do not add */
  81.     /* or remove fields, just change them! */
  82.     {"", 0, 255, 0},
  83.     {"", 0, 255, 0},
  84.     {"", 0, 255, 0},
  85.     {"", 0, 255, 0},
  86.     {"", 0, 255, 0},
  87.     {"", 0, 255, 0},
  88.     {"", 0, 255, 0},
  89.     {"", 0, 255, 0},
  90.     {"", 0, 255, 0},
  91.     {"", 0, 255, 0},
  92.     {"", 0, 255, 0},
  93.     {"", 0, 255, 0},
  94.     {"", 0, 255, 0},
  95.     {"", 0, 255, 0},
  96.     {"", 0, 255, 0},
  97.     {"", 0, 255, 0},
  98.     {"", 0, 255, 0},
  99.     {"", 0, 255, 0},
  100.     {"", 0, 255, 0},
  101.  
  102.     /* Strings - we start these out at position 50 */
  103.     {"P",             1,  0, 0},
  104.     {"N",             1,  1, 0},
  105.     {"Cs",                      2,  2, 0},
  106.     {"Pw",             2,  3, 0},
  107.     {"Os",             2,  4, 0},
  108.     {"st",             2,  5, 0},
  109.     {"plastic",             7,  6, 0},
  110.     {"hplastic",         8,  7, 0},
  111.     {"eplastic",         8,  8, 0},
  112.     {"heplastic",         9,  9, 0},
  113.     {"constant",         8,  10, 0},
  114.     {"ambientlight",        12, 11, 0},
  115.     {"lightcolor",        10, 12, 0},
  116.     {"distantlight",        12, 13, 0},
  117.     {"intensity",         9, 14, 0},
  118.     {"file",             4, 15, 0},
  119.     {"rgb",             3, 16, 0},
  120.     {"rgba",             4, 17, 0},
  121.     {"Ka",             2, 18, 0},
  122.     {"Kd",             2, 19, 0},
  123.     {"Ks",             2, 20, 0},
  124.     {"specularcolor",        13, 21, 0}, 
  125.     {"roughness",         9, 22, 0},
  126.     {"fov",             3, 23, 0},
  127.     {"perspective",        11, 24, 0},
  128.     {"to",             2, 25, 0},
  129.     {"framebuffer",         11, 26, 0}
  130. };
  131.  
  132. /* initialize tokenbuffer */
  133. void mrti_init()
  134. {
  135.     if(tokenbuffer) free(tokenbuffer);
  136.     tokenbuffer = (unsigned char *)malloc(BUFFERSIZE);
  137.     tokenbuffer[0] = (char)0;
  138.     limit = (unsigned char *)(tokenbuffer + BUFFERSIZE);
  139.     ptr = tokenbuffer;
  140. }
  141.  
  142. /* reset the ptr & tokenbuffer */
  143. void mrti_reset()
  144. {
  145.     ptr = tokenbuffer;
  146.     tokenbuffer[0] = (char)0;
  147. }
  148.  
  149. /* quick copy routine w/ ptr update */
  150. void cat(unsigned char *s, char *a)
  151. {
  152.     while(*(s++)=(*(a++))) ptr++;
  153. }
  154.  
  155.  
  156. /* routine will check buffer for possible overun, will realloc if needed */
  157. /* generally, "worst case" values should be passed to check_buffer       */
  158. void check_buffer(int length)
  159. {
  160.     if((unsigned char *)(ptr+length)>(unsigned char *)limit) {
  161.         /* optinally check for maximum buffer allocation here */
  162.     long used = ptr - tokenbuffer;
  163.     long avail = limit - tokenbuffer;
  164.         /* Buffer grows exponentially, by factor of 1.5 each time */
  165.     do { avail += avail>>1; } while(used+length >= avail);
  166.     tokenbuffer = (unsigned char *)realloc(tokenbuffer, avail);
  167.     ptr = tokenbuffer + used;
  168.     limit = tokenbuffer + avail;
  169.     }
  170. }
  171.  
  172. /* process variable size token list */
  173. void mrti(int a1, ... )
  174. {
  175.     va_list alist;
  176.  
  177.     va_start(alist, a1);
  178.  
  179.     switch((int)(_mgribc->render_device & (RMD_BINARY|RMD_ASCII)))
  180.     {
  181.     case (int)RMD_BINARY: binary_token(a1, &alist); break;
  182.     case (int)RMD_ASCII:  ascii_token(a1, &alist); break;
  183.     }
  184.     va_end(alist);
  185. }
  186.  
  187. /* return 1 when supplied token requires its own (ascii) line, 0 otherwise */
  188. int line_initializer(int token)
  189. {
  190.     /* THIS IS HACKISH - IT WILL CREATE A LINE FEED BEFORE */
  191.     /* IT CREATES THE NEW LINE, WHICH ISN'T ALWAYS GOOD!!  */
  192.     if(token<STRINGBASE||token==mr_comment||token==mr_section||
  193.        (token>=mr_P && token<=mr_Os)) return 1;
  194.     else return 0;
  195. }
  196.  
  197. /* ASCII SUBPROCESSING */
  198. void ascii_token(int token, va_list *alist)
  199. {
  200. int i;
  201. int count, number;
  202. int subsize;
  203. static int arraysize;
  204. static int expectSubArray=0;
  205. static char astring[128];
  206. double nextfloat; /* va_arg converts floats to doubles */
  207. float *floatptr;
  208. char *s;
  209. int len, add;
  210.  
  211.     do {
  212.     
  213.     if(expectSubArray && (token!=mr_subarray3)) {
  214.         /* ERROR */
  215.     }
  216.     
  217.     /* check to see if we need to start a new line */
  218.     if(line_initializer(token) && *(ptr-1)!='\n') *(ptr++)='\n';
  219.     
  220.     switch(token) {
  221.     
  222.     case mr_section:
  223.     check_buffer(SECTIONWIDTH); /* should not exceed this */
  224.         s = va_arg(*alist, char*);
  225.         len = strlen(s);
  226.     if(len+3>SECTIONWIDTH) len = SECTIONWIDTH-3; /* 3 added characters */
  227.     *(ptr++)='\n';
  228.     cat(ptr,"# ");
  229.         cat(ptr,s);
  230.     cat(ptr," ");
  231.     
  232.     len = SECTIONWIDTH - 3 - len;
  233.         while((len--)>0) *(ptr++)='*';
  234.     break;
  235.  
  236.     case mr_comment:
  237.     s = va_arg(*alist, char*);
  238.     len = strlen(s);
  239.     check_buffer(len+2);
  240.     cat(ptr,"# ");
  241.     cat(ptr,s);
  242.     break;
  243.  
  244.     case mr_header:
  245.         s = va_arg(*alist, char*);
  246.     len = strlen(s);
  247.     check_buffer(len+2);
  248.     cat(ptr,"##");
  249.     cat(ptr,s);
  250.     break;
  251.     
  252.     case mr_nl:
  253.         /* check for space */
  254.     check_buffer(2);
  255.     if(*(ptr-1)==' ') ptr--;
  256.         *(ptr++)='\n';
  257.     break;
  258.     
  259.     case mr_array:
  260.         arraysize = va_arg(*alist, int);
  261.     check_buffer(arraysize*16+4); /* how else can we do this? */
  262.     *(ptr++)='[';
  263.     for(i=0;i<arraysize;i++) {
  264.         nextfloat = va_arg(*alist, double);
  265.         sprintf(astring,"%g ",nextfloat);
  266.         cat(ptr, astring);
  267.     }
  268.     *(--ptr)=0; /* get rid of space */
  269.     cat(ptr,"] ");
  270.     break;
  271.     
  272.     case mr_buildarray:
  273.         arraysize = va_arg(*alist, int);
  274.     check_buffer(1);
  275.     expectSubArray = 1;
  276.     *(ptr++)='[';
  277.     break;
  278.  
  279.     case mr_parray:
  280.     {
  281.         int size;
  282.         size = va_arg(*alist, int);
  283.     check_buffer(2+16*size);
  284.     *(ptr++)='[';
  285.     /* if arraysize<0 then ERROR */
  286.     floatptr = va_arg(*alist, float*);
  287.     for(i=0;i<size;i++) {
  288.         sprintf(astring,"%g ",*(floatptr++));
  289.         cat(ptr,astring);
  290.     }
  291.     *(--ptr)=0; /* get rid of unwanted space */
  292.     cat(ptr,"] ");
  293.     break;
  294.     }
  295.     
  296.     case mr_subarray3:
  297.     check_buffer(16*3+7);
  298.     arraysize-=3;
  299.     /* if arraysize<0 then ERROR */
  300.         floatptr = va_arg(*alist, float*);
  301.         sprintf(astring,"%g %g %g   ",
  302.         *(floatptr),*(floatptr+1),*(floatptr+2));
  303.     cat(ptr,astring);
  304.     if(arraysize<=0) {
  305.         expectSubArray = 0;
  306.         *(ptr-=3)=0; /* get rid of unwanted spaces */
  307.         cat(ptr,"] ");
  308.     }
  309.     break;
  310.  
  311.     case mr_int:
  312.         number = va_arg(*alist, int);
  313.     check_buffer(16);
  314.     sprintf(astring,"%d ",number);
  315.     cat(ptr,astring);
  316.     break;
  317.  
  318.     case mr_float:
  319.         nextfloat = va_arg(*alist, double);
  320.     check_buffer(16);
  321.     sprintf(astring,"%g ",nextfloat);
  322.     cat(ptr,astring);
  323.     break;
  324.     
  325.     case mr_intseq:
  326.         /* OBSOLETE */
  327.         count = va_arg(*alist, int);
  328.     check_buffer(count*16);
  329.     for(i=0;i<count;i++) {
  330.         number = va_arg(*alist, int);
  331.         sprintf(astring,"%d ",number);
  332.         cat(ptr,astring);
  333.     }
  334.     *(--ptr)=0;
  335.     break;
  336.  
  337.     case mr_string:
  338.     {
  339.         char *string;
  340.     string = va_arg(*alist, char *);
  341.     len = strlen(string);
  342.     check_buffer(len+3);
  343.     *(ptr++)='"';
  344.     cat(ptr,string);
  345.     *(ptr++)='"';
  346.     *(ptr++)=' ';
  347.     break;
  348.     }
  349.  
  350.     case mr_embed:
  351.     {
  352.         /* directly embed a string */
  353.         char *string;
  354.     string = va_arg(*alist, char *);
  355.     len = strlen(string);
  356.     check_buffer(len);
  357.     cat(ptr,string);
  358.     break;
  359.     }
  360.     /* these requests require a trailing line feed */
  361.     case mr_attributebegin:
  362.     case mr_attributeend:
  363.     case mr_transformbegin:
  364.     case mr_transformend:
  365.     case mr_identity:
  366.     case mr_polygon:
  367.     case mr_worldbegin:
  368.     case mr_worldend:
  369.     case mr_frameend:
  370.     check_buffer(table[token].len);
  371.     cat(ptr,table[token].name);
  372.     /*
  373.     *(ptr++) = '\n';
  374.     */
  375.     break;
  376.  
  377.     /* these requests require a trailing space */
  378.     case mr_color:
  379.     case mr_opacity:
  380.     case mr_format:
  381.     case mr_display:
  382.     case mr_screenwindow:
  383.     case mr_clipping:
  384.     case mr_concattransform:
  385.     case mr_projection:
  386.     case mr_lightsource:
  387.     case mr_illuminate:
  388.     case mr_surface:
  389.     case mr_sphere:
  390.     case mr_patchmesh:
  391.     case mr_rotate:
  392.     case mr_translate:
  393.     case mr_cylinder:
  394.     case mr_nupatch:
  395.     case mr_option:
  396.     case mr_shadinginterpolation:
  397.     case mr_shadingrate:
  398.     case mr_framebegin:
  399.     check_buffer(table[token].len+1);
  400.         cat(ptr,table[token].name);
  401.     *(ptr++)=' ';
  402.     break;
  403.     
  404.     /* anything left over should be a string  */
  405.     /* which requires quotes & trailing space */
  406.     /* (THIS SHOULD BE MOVED OUT OF SWITCH)  */
  407.     default:
  408.     check_buffer(table[token].len+3);
  409.         *(ptr++)='"';
  410.         cat(ptr,table[token].name);
  411.     *(ptr++)='"';
  412.     *(ptr++)=' ';
  413.     break;
  414.  
  415.     }
  416.             
  417.     } while ((token=va_arg(*alist, int))!=mr_NULL);
  418. }
  419.  
  420.  
  421. /* BINARY SUBPROCESSING */
  422. /* NOTE: some hardware will not support copying data types > 1 byte into an
  423.  * arbitrary (unaligned) location. e.g.
  424.  *    *(unsigned short *)ptr = anUnsignedVariable
  425.  * may be an illegal instruction. Therefore, macros which will copy these
  426.  * values one byte at a time follow here and are used where needed. These
  427.  * macros will work only with float sizes of 4 bytes (IEEE) & unsigned short
  428.  * int sizes of 2 bytes
  429.  */
  430.  
  431. #define COPYUSHORT( value )    *ptr++ = ((char *)&value)[0];\
  432.                 *ptr++ = ((char *)&value)[1]
  433. #define COPYFLOAT( value )    *ptr++ = ((char *)&value)[0];\
  434.                 *ptr++ = ((char *)&value)[1];\
  435.                 *ptr++ = ((char *)&value)[2];\
  436.                 *ptr++ = ((char *)&value)[3]
  437.  
  438. void binary_token(int token, va_list *alist)
  439. {
  440. int i;
  441. static int expectSubArray=0;
  442. static int arraysize;
  443. float *floatptr;
  444.  
  445.     if(expectSubArray && (token!=mr_subarray3)) {
  446.         /* ERROR */
  447.     }
  448.  
  449.     do {
  450.     
  451.     if(token>=STRINGBASE & token<mr_array) {
  452.         /* The token is a string defintion/request */
  453.     if(!table[token].defined) {
  454.         check_buffer(7 + table[token].len);
  455.         *(ptr++)=STRINGDEF;
  456.         *(ptr++)=table[token].reqn;
  457.         if(table[token].len<16) {
  458.             *(ptr++)=STRINGENCODE+table[token].len;
  459.         } else {
  460.             unsigned short length;
  461.         length = (unsigned short) table[token].len;
  462.             *(ptr++)=LNGSTRINGENCODE;
  463.         COPYUSHORT(length);
  464.         }
  465.         cat(ptr,table[token].name);
  466.         table[token].defined = 1;
  467.     }
  468.     *(ptr++)=STRINGREF;
  469.     *(ptr++)=table[token].reqn;
  470.     }
  471.     
  472.     else switch(token) {
  473.     
  474.     /* THESE SHOULD BE MOVE BEFORE SWITCH */
  475.     /* AND TURNED INTO A SPECIAL CASE    */
  476.     case mr_attributebegin:
  477.     case mr_attributeend:
  478.     case mr_transformbegin:
  479.     case mr_transformend:
  480.     case mr_identity:
  481.     case mr_polygon:
  482.     case mr_worldbegin:
  483.     case mr_worldend:
  484.     case mr_color:
  485.     case mr_format:
  486.     case mr_display:
  487.     case mr_screenwindow:
  488.     case mr_clipping:
  489.     case mr_concattransform:
  490.     case mr_projection:
  491.     case mr_lightsource:
  492.     case mr_illuminate:
  493.     case mr_surface:
  494.     case mr_sphere:
  495.     case mr_patchmesh:
  496.     case mr_translate:
  497.     case mr_rotate:
  498.     case mr_cylinder:
  499.     case mr_nupatch:
  500.     case mr_option:
  501.     case mr_shadinginterpolation:
  502.     case mr_shadingrate:
  503.     case mr_framebegin:
  504.     case mr_frameend:
  505.         check_buffer(7+table[token].len);
  506.     if(!table[token].defined) {
  507.         /* we must define it */
  508.         *(ptr++)=RIREQDEF;
  509.         *(ptr++)=table[token].reqn;
  510.         if(table[token].len<16) {
  511.             *(ptr++)=STRINGENCODE+table[token].len;
  512.         } else {
  513.             unsigned short length;
  514.         length = (unsigned short) table[token].len;
  515.         *(ptr++)=LNGSTRINGENCODE;
  516.         COPYUSHORT(length);
  517.         }
  518.         cat(ptr,table[token].name);
  519.         table[token].defined = 1;
  520.     }
  521.     *(ptr++)=RIREQREF;
  522.     *(ptr++)=table[token].reqn;
  523.         break;
  524.     
  525.     case mr_array:
  526.     {
  527.         unsigned char arraycount;
  528.     unsigned char *p;
  529.     float f;
  530.         arraycount = (unsigned char)va_arg(*alist, int);
  531.     check_buffer(2+4*arraycount);
  532.     *(ptr++)=FLOATARRAYDEF;
  533.     *(ptr++)=arraycount;
  534.     for(i=0;i<arraycount;i++) {
  535.         /* will float be the same on each platform? (ieee?)*/
  536.         /* IS THIS NEXT STEP LEGAL?!? */
  537.         f = (float) va_arg(*alist, double);
  538.         COPYFLOAT(f);
  539.     }
  540.     break;
  541.     }
  542.     
  543.     case mr_buildarray:
  544.     {
  545.         unsigned char arraycount;
  546.     arraysize = va_arg(*alist, int);
  547.     arraycount = (unsigned char)arraysize;
  548.     check_buffer(2);
  549.     *(ptr++)=FLOATARRAYDEF;
  550.     *(ptr++)=arraycount;
  551.     expectSubArray = 1;
  552.     break;
  553.     }
  554.     
  555.     case mr_subarray3:
  556.     {
  557.         arraysize-=3;
  558.     if(arraysize<0) /* ERROR */;
  559.     check_buffer(12); /* 3*sizeof(float) */
  560.         floatptr = va_arg(*alist, float*);
  561.     bcopy((char *)floatptr, (char *)ptr, 3*sizeof(float));
  562.     ptr+=3*sizeof(float);
  563.     if(arraysize<=0) {
  564.         expectSubArray = 0;
  565.     }
  566.     break;
  567.     }
  568.   
  569.     case mr_parray:
  570.     {
  571.         unsigned char arraycount;
  572.     arraycount = (unsigned char)va_arg(*alist, int);
  573.     check_buffer(2+arraycount*4);
  574.     *(ptr++)=FLOATARRAYDEF;
  575.     *(ptr++)=arraycount;
  576.     floatptr = va_arg(*alist, float*);
  577.     bcopy((char *)floatptr, (char *)ptr, arraycount*sizeof(float));
  578.     ptr+=arraycount*sizeof(float);
  579.     if(arraysize<=0) {
  580.         expectSubArray = 0;
  581.     }
  582.     break;
  583.     }
  584.  
  585.     case mr_int:
  586.     {
  587.         unsigned short number;
  588.     check_buffer(3);
  589.         number = (unsigned short)va_arg(*alist, int);
  590.     *(ptr++) = INTEGER;
  591.     COPYUSHORT(number);
  592.     break;
  593.     }
  594.  
  595.     case mr_float:
  596.     {
  597.         float afloat;
  598.     check_buffer(5);
  599.         afloat = (float)va_arg(*alist, double);
  600.     *(ptr++) = FLOAT;
  601.     COPYFLOAT(afloat);
  602.     break;
  603.     }
  604.     
  605.     case mr_intseq:
  606.     {
  607.         /* OBSOLETE */
  608.         unsigned short number;
  609.     int  count;
  610.     count = va_arg(*alist, int);
  611.     check_buffer(number*2);
  612.     for(i=0;i<count;i++) {
  613.         number = (unsigned short)va_arg(*alist, int);
  614.         *(ptr++) = INTEGER;
  615.         COPYUSHORT(number);
  616.     }
  617.     break;
  618.     }
  619.  
  620.     case mr_string:
  621.     {
  622.         unsigned short length;
  623.     char *string;
  624.     string = va_arg(*alist, char *);
  625.     length = (unsigned short) strlen(string);
  626.     check_buffer(3+length);
  627.     if(length<16) {
  628.         *(ptr++)=STRINGENCODE+(char)length;
  629.     } else {
  630.         *(ptr++)=LNGSTRINGENCODE;
  631.         COPYUSHORT(length);
  632.     }
  633.     cat(ptr,string);
  634.     break;
  635.     }
  636.     
  637.     case mr_embed:
  638.     {
  639.         /* no attempt is made to encode this becuase it's so general */
  640.     char *string;
  641.     int length;
  642.     string = va_arg(*alist, char *);
  643.     length = strlen(string);
  644.     check_buffer(length);
  645.         cat(ptr,string);
  646.     break;
  647.     }
  648.     
  649.     case mr_nl:
  650.         /* temporary for debugging (puts tokens on spereate lines) */
  651.         /* printf("\n"); */
  652.     break;
  653.     
  654.     } /* switch */    
  655.     } while ((token=va_arg(*alist, int))!=mr_NULL);
  656. }
  657.